// bind call apply 都是用于修改this指向的
// call 和 apply 的不同在于 apply传入的是数组

// call和apply改变了函数的this上下文后便执行该函数,而bind则是返回改变了上下文后的一个函数
// call、bind和apply的第一个参数都是要改变上下文的对象，
// 而call、bind从第二个参数开始以参数列表的形式展现apply则是把除了改变上下文对象的参数放在一个数组里面作为它的第二个参数

// call
Function.prototype.myCall = function(context) {
    // 1. 判断context 传值与否
    context = context || this;
    // 2. 给context指定一个方法，指向this
    context.fn = this;
    // 3. 获取args
    let args = [...arguments].slice(1);
    // 4. 执行fn
    context.fn(args);
    // 5. 删除自定义方法
};


// apply
Function.prototype.myApply = function(context, args=[]) {
    context = context || window;
    context.fn = this;
    context.fn(args);
};


// bind
Function.prototype.myBind = function(context) {
    let self = this;
    let args = [...arguments].slice(1);

    return function() {
        let newArgs = [...arguments];

        return self.apply(context, [...args, ...newArgs]);
    };
};
